﻿using System;
using System.Linq.Expressions;
using élénkPróbája.native;

namespace élénkPróbája.assets
{
    public class LitLocalizedStringSource : IStringSource
    {
        readonly Func<string> accessor;
        readonly Type resourceType;
        readonly string resourceName;

        /// <summary>
        /// Creates a new instance of the LocalizedErrorMessageSource class using the specified resource name and resource type.
        /// </summary>
        /// <param name="resourceType">The resource type</param>
        /// <param name="resourceName">The resource name</param>
        /// <param name="resourceAccessorBuilder">Strategy used to construct the resource accessor</param>
        public LitLocalizedStringSource(Type resourceType, string resourceName, IResourceAccessorBuilder resourceAccessorBuilder)
        {
            var resourceAccessor = resourceAccessorBuilder.GetResourceAccessor(resourceType, resourceName);

            this.resourceType = resourceAccessor.ResourceType;
            this.resourceName = resourceAccessor.ResourceName;
            this.accessor = resourceAccessor.Accessor;
        }

        /// <summary>
        /// Creates an IErrorMessageSource from an expression: () => MyResources.SomeResourceName
        /// </summary>
        /// <param name="expression">The expression </param>
        /// <param name="resourceProviderSelectionStrategy">Strategy used to construct the resource accessor</param>
        /// <returns>Error message source</returns>
        public static IStringSource CreateFromExpression(Expression<Func<string>> expression, IResourceAccessorBuilder resourceProviderSelectionStrategy)
        {
            var constant = expression.Body as ConstantExpression;

            if (constant != null)
            {
                return new LitStaticStringSource((string)constant.Value);
            }

            var member = expression.GetMember();

            if (member == null)
            {
                throw new InvalidOperationException("Only MemberExpressions an be passed to BuildResourceAccessor, eg () => Messages.MyResource");
            }

            var resourceType = member.DeclaringType;
            var resourceName = member.Name;
            return new LitLocalizedStringSource(resourceType, resourceName, resourceProviderSelectionStrategy);
        }

        /// <summary>
        /// Construct the error message template
        /// </summary>
        /// <returns>Error message template</returns>
        public string GetString()
        {
            return accessor();
        }

        /// <summary>
        /// The name of the resource if localized.
        /// </summary>
        public string ResourceName
        {
            get { return resourceName; }
        }

        /// <summary>
        /// The type of the resource provider if localized.
        /// </summary>
        public Type ResourceType
        {
            get { return resourceType; }
        }
    }
}